#ifndef TETRAQUAD_H
#define TETRAQUAD_H

#include "QGLShaderProgram"
#include "Object3D.h"
#include "QVector"

#define SPHERE      (QMatrix4x4(1.0,0.0,0.0,0.0, 0.0, 1.0,0.0, 0.0, 0.0,0.0, 1.0,0.0, 0.0, 0.0,0.0,-0.25))
#define SADDLE      (QMatrix4x4(1.0,0.0,0.0,0.0, 0.0, 0.0,0.0,-0.5, 0.0,0.0,-1.0,0.0, 0.0,-0.5,0.0, 0.0 ))
#define PARABOLOID  (QMatrix4x4(1.0,0.0,0.0,0.0, 0.0, 0.0,0.0,-0.5, 0.0,0.0, 1.0,0.0, 0.0,-0.5,0.0, 0.0 ))
#define CONE        (QMatrix4x4(1.0,0.0,0.0,0.0, 0.0,-1.0,0.0, 0.0, 0.0,0.0, 1.0,0.0, 0.0, 0.0,0.0, 0.0 ))
#define CYLINDER    (QMatrix4x4(1.0,0.0,0.0,0.0, 0.0, 0.0,0.0, 0.0, 0.0,0.0, 1.0,0.0, 0.0, 0.0,0.0,-0.25))
#define PARA2SHEETS (QMatrix4x4(1.0,0.0,0.0,0.0, 0.0,-1.0,0.0, 0.0, 0.0,0.0, 1.0,0.0, 0.0, 0.0,0.0, 0.25))

class TetraQuad : public Object3D
{
    QVector<QVector4D> vertices;
    QVector<QMatrix4x4> quadrics;
    QMatrix4x4 w;

    QVector<QVector4D> points;

    QGLShaderProgram program;

    bool show;

public:
    explicit TetraQuad(const QVector3D& center = QVector3D(),
                    QObject *parent = 0);
    explicit TetraQuad(const TetraQuad& tt);
    ~TetraQuad();

    virtual Object3D* copy() const;

    QVector<QVector4D> getVertices();
    void setQuadric(const QMatrix4x4&, int idx);

    void buildPointCloud();

    float eval(const QVector4D& p);
    float evalByBari(const QVector4D& bC, QVector4D& p);

    QVector4D bariCoord(const QVector4D& p);

    bool isProgramLinked();
    void setShow(bool v);

private:
    virtual void drawGeometry(void);
    void buildObject();
};

#endif // TETRAQUAD_H
